using System;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections.Generic;

namespace Publish.Services
{
    /// <summary>
    /// 代码行数统计
    /// </summary>
    public class TotalLineService
    {
        #region Field

        private Int32 _totalLine = 0;//代码行数
        private List<Tuple<String, String>> fileList = new List<Tuple<String, String>>();//文件列表
        private String[] fileExtension = new[] { ".cs", ".config", ".xml", ".html", ".htm", ".cshtml", ".asp", ".js", ".css", ".xcscheme", ".java" };//需要统计行数的文件后缀

        #endregion

        #region Constructor

        public TotalLineService()
        {

        }

        #endregion

        #region Delegate

        /// <summary>
        /// 完成一个代理
        /// </summary>
        /// <param name="sender"></param>
        public delegate void OnCompleteHander(String sender);

        /// <summary>
        /// 显示
        /// </summary>
        public event OnCompleteHander ShowCurrentItem;

        #endregion

        #region Public Method

        /// <summary>
        /// 获取代码行数
        /// </summary>
        /// <param name="path"></param>
        public void GetTotalLine(String path)
        {
            if (String.IsNullOrWhiteSpace(path)) return;

            fileList = new List<Tuple<String, String>>();

            _totalLine = 0;

            GetFileList(path, ref fileList);

            if (fileList.Count == 0) return;

            var list = fileList.GroupBy(x => x.Item1).ToList();

            foreach (var item in list)
            {
                var currentList = fileList.Where(x => x.Item1 == item.Key).ToList();
                new Thread(() => GetLine(currentList)) { IsBackground = true }.Start();
            }
        }


        #endregion

        #region Private Method

        /// <summary>
        /// 获取文件集代码行数
        /// </summary>
        public void GetLine(List<Tuple<String, String>> list)
        {
            foreach (var item in list)
            {
                Int32 line = 0; //第一行有效代码行号

                using (var file = new System.IO.StreamReader(item.Item2, Encoding.UTF8))
                {
                    for (var i = 0; file.ReadLine() != null; i++)
                    {
                        line += 1;
                    }

                    _totalLine += line;

                    ShowCurrentItem(_totalLine.ToString("N0"));//显示程序已用时
                }
            }
        }

        /// <summary>
        /// 获取文件列表
        /// </summary>
        /// <param name="dir">目标路径</param>
        /// <param name="list">文件列表</param>
        private void GetFileList(String dir, ref List<Tuple<String, String>> list)
        {
            var source = new DirectoryInfo(dir);//目标路径（项目所在路径）

            var files = source.GetFiles();//获取文件

            var dirs = source.GetDirectories();//返回路径信息

            foreach (DirectoryInfo info in dirs)
            {
                if (info.Name == "$tf") continue;// TFS 数据文件

                GetFileList(info.FullName, ref list);//递归寻找文件夹下面的
            }

            foreach (var fileInfo in files)
            {
                var extension = fileInfo.Extension.ToLower();

                if (extension == ".xml")
                {
                    var path = fileInfo.FullName.Replace(".xml", ".dll");
                    if (File.Exists(path)) continue;//跳过DLL注释文件
                }

                if (fileExtension.Contains(extension.ToLower()))
                    list.Add(new Tuple<String, String>(extension.ToLower(), fileInfo.FullName));//记录Class文件
            }
        }

        #endregion
    }
}